None
Для работы получены файл Daily_Reach_OTS.xlsx
Предоставленные массивы данных об отдельных аудиториях диджитал-ресурсов среди населения России в возрасте 12 лет и старше в динамике за 3 месяца. Содержаться как общие показатели среди населения, так и в разбивке на возрастные группы и устройство контакта - Web Desktop (ПК и ноутбуки), App Mobile (Мобильное приложение), Web Mobile (Мобильный браузер). Все файлы содержат идентичный набор ресурсов за один и тот же период.
| ADR | Average Daily Reach |
| Рассчитывается как среднее арифметическое Reach каждого из дней, входящих в заданный период. Даже если данные по медиа объекту отсутствуют в части дней из отобранного периода, среднее арифметическое рассчитывается по всем дням, а не по тем, где были данные. | |
| OTS | Opportunity To See |
| Общее количество загрузок страниц/ открытий приложений медиа объекта за указанный период в рамках заданной соц.-дем. группы. |
Провести анализ EDA данных из файла Daily_Reach_OTS с метриками ADR и OTS:
Daily_Reach_OTSдо 12 лет,от 12 до 24 лет,от 24 до 34 лет,от 34 до 44 лет,от 44 до 54 лет,от 55 летпримечание. Для суммарных, по всем возрастных категорий пользователей анализ проводить не будем. Проведем сравнение по возрастным группам).# Все import соберем в начале проекта:
import warnings
warnings.filterwarnings('ignore')
import pandas as pd
import os
import seaborn as sns
import re
from skimpy import skim, clean_columns
from datetime import datetime
from tqdm.auto import tqdm
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from statsmodels.tsa.stattools import adfuller
from statsmodels.tsa.seasonal import seasonal_decompose
from datetime import datetime, timedelta
# Размер окна для проверки стационарности временного ряда
WINDOW_STATIONARITY = 7
# Настроим вид таблиц:
pd.set_option("display.max_rows", 50)
pd.set_option("display.max_columns", 50)
# Настроим, чтобы числа в датасетах отражались без знаков после запятой
pd.set_option('display.float_format', '{:.0f}'.format)
Изучил файл Daily_Reach_OTS.xlsx и привёл его к формату csv:
# Вспомогательная функция для чтения файлов с данными
def load_dataset(file_name, separator):
'''
Функция для проверки нахождения файла и загрузки датафрейма.
'''
if os.path.exists(file_name):
data = pd.read_csv(file_name, sep = separator)
print('Dataset "', file_name, '" is loaded successfully.', sep='')
return data
else:
print('Something with', file_name, 'is wrong!')
# Загрузка данных по фактическому включению/выключению пиплметра
df_dro_full = load_dataset('Daily_Reach_OTS_total.csv', ';')
Dataset "Daily_Reach_OTS_total.csv" is loaded successfully.
Создаю вспомогательную функцию для изучения датафреймов.
def view_skim_df(df):
'''
Функция для единообразного изучения датафреймов.
1. Контроль размера датафрейма.
2. Вывод основных данных по датафрейму.
3. Распечатка на экране первых трёх объектов датафрейма.
'''
skim(df)
display(df.head(3))
print('Количество дубликатов:', df.duplicated().sum())
print('Полное количество пропущенных значений по всем признакам:',
df.isnull().sum().sum())
return
# Изучим содержимое датафрейма:
view_skim_df(df_dro_full)
╭──────────────────────────────────────────────── skimpy summary ─────────────────────────────────────────────────╮ │ Data Summary Data Types │ │ ┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┓ ┏━━━━━━━━━━━━━┳━━━━━━━┓ │ │ ┃ dataframe ┃ Values ┃ ┃ Column Type ┃ Count ┃ │ │ ┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━┩ ┡━━━━━━━━━━━━━╇━━━━━━━┩ │ │ │ Number of rows │ 516 │ │ string │ 151 │ │ │ │ Number of columns │ 152 │ │ int32 │ 1 │ │ │ └───────────────────┴────────┘ └─────────────┴───────┘ │ │ number │ │ ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━┓ │ │ ┃ column_name ┃ NA ┃ NA % ┃ mean ┃ sd ┃ p0 ┃ p25 ┃ p75 ┃ p100 ┃ hist ┃ │ │ ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━┩ │ │ │ age │ 0 │ 0 │ 29 │ 19 │ 0 │ 12 │ 45 │ 55 │ ██████ │ │ │ └──────────────────────┴───────┴──────────┴──────────┴───────┴───────┴────────┴────────┴─────────┴───────────┘ │ │ string │ │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓ │ │ ┃ column_name ┃ NA ┃ NA % ┃ words per row ┃ total words ┃ │ │ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━┩ │ │ │ Date │ 0 │ 0 │ 1 │ 520 │ │ │ │ 2gis Web Desktop ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ 2gis Web Desktop OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ 2 gis App Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ 2gis App Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ 2gis Web Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ 2gis Web Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Discord Web Desktop │ 0 │ 0 │ 1 │ 520 │ │ │ │ Discord Web Desktop │ 0 │ 0 │ 1 │ 520 │ │ │ │ Discord App Mobile A │ 0 │ 0 │ 1 │ 520 │ │ │ │ Discord App Mobile O │ 0 │ 0 │ 1 │ 520 │ │ │ │ Discord Web Mobile A │ 0 │ 0 │ 1 │ 520 │ │ │ │ Discord Web Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Facebook Web Desktop │ 0 │ 0 │ 1 │ 520 │ │ │ │ Facebook Web Desktop │ 0 │ 0 │ 1 │ 520 │ │ │ │ Facebook App Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Facebook App Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Facebook Web Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Facebook Web Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Google Карты Web Des │ 0 │ 0 │ 1 │ 520 │ │ │ │ Google Карты Web Des │ 0 │ 0 │ 1 │ 520 │ │ │ │ Google Карты App Mob │ 0 │ 0 │ 1 │ 520 │ │ │ │ Google Карты App Mob │ 0 │ 0 │ 1 │ 520 │ │ │ │ Google Карты Web Mob │ 0 │ 0 │ 1 │ 520 │ │ │ │ Google Карты Web Mob │ 0 │ 0 │ 1 │ 520 │ │ │ │ Google Новости Web D │ 0 │ 0 │ 1 │ 520 │ │ │ │ Google Новости Web D │ 0 │ 0 │ 1 │ 520 │ │ │ │ Google Новости App M │ 0 │ 0 │ 1 │ 520 │ │ │ │ Google Новости App M │ 0 │ 0 │ 1 │ 520 │ │ │ │ Google Новости Web M │ 0 │ 0 │ 1 │ 520 │ │ │ │ Google Новости Web M │ 0 │ 0 │ 1 │ 520 │ │ │ │ Kp Web Desktop ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ Kp Web Desktop OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Kp App Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ Kp App Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Kp Web Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ Kp Web Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Mail.ru Новости Web │ 0 │ 0 │ 1 │ 520 │ │ │ │ Mail.ru Новости Web │ 0 │ 0 │ 1 │ 520 │ │ │ │ Mail.ru Новости App │ 0 │ 0 │ 1 │ 520 │ │ │ │ Mail.ru Новости App │ 0 │ 0 │ 1 │ 520 │ │ │ │ Mail.ru Новости Web │ 0 │ 0 │ 1 │ 520 │ │ │ │ Mail.ru Новости Web │ 0 │ 0 │ 1 │ 520 │ │ │ │ OK Web Desktop ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ OK Web Desktop OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ OK App Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ App Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ OK Web Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ OK Web Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Sbermarket Web Deskt │ 0 │ 0 │ 1 │ 520 │ │ │ │ Sbermarket Web Deskt │ 0 │ 0 │ 1 │ 520 │ │ │ │ Sbermarket App Mobil │ 0 │ 0 │ 1 │ 520 │ │ │ │ Sbermarket App Mobil │ 0 │ 0 │ 1 │ 520 │ │ │ │ Sbermarket Web Mobil │ 0 │ 0 │ 1 │ 520 │ │ │ │ Sbermarket Web Mobil │ 0 │ 0 │ 1 │ 520 │ │ │ │ Sbermegamarket Web D │ 0 │ 0 │ 1 │ 520 │ │ │ │ Sbermegamarket Web D │ 0 │ 0 │ 1 │ 520 │ │ │ │ Sbermegamarket App M │ 0 │ 0 │ 1 │ 520 │ │ │ │ Sbermegamarket App M │ 0 │ 0 │ 1 │ 520 │ │ │ │ Sbermegamarket Web M │ 0 │ 0 │ 1 │ 520 │ │ │ │ Sbermegamarket Web M │ 0 │ 0 │ 1 │ 520 │ │ │ │ Smi2 Web Desktop ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ Smi2 Web Desktop OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Smi2 App Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ Smi2 App Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Smi2 Web Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ Smi2 Web Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Steam Web Desktop AD │ 0 │ 0 │ 1 │ 520 │ │ │ │ Steam Web Desktop OT │ 0 │ 0 │ 1 │ 520 │ │ │ │ Steam App Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ Steam App Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Steam Web Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ Steam Web Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Telegram Web Desktop │ 0 │ 0 │ 1 │ 520 │ │ │ │ Telegram Web Desktop │ 0 │ 0 │ 1 │ 520 │ │ │ │ Telegram App Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Telegram App Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Telegram Web Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Telegram Web Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Tiktok Web Desktop A │ 0 │ 0 │ 1 │ 520 │ │ │ │ Tiktok Web Desktop O │ 0 │ 0 │ 1 │ 520 │ │ │ │ Tiktok App Mobile AD │ 0 │ 0 │ 1 │ 520 │ │ │ │ Tiktok App Mobile OT │ 0 │ 0 │ 1 │ 520 │ │ │ │ Tiktok Web Mobile AD │ 0 │ 0 │ 1 │ 520 │ │ │ │ Tiktok Web Mobile OT │ 0 │ 0 │ 1 │ 520 │ │ │ │ Vedomosti │ 0 │ 0 │ 1 │ 520 │ │ │ │ Web Desktop Web Desk │ 0 │ 0 │ 1 │ 520 │ │ │ │ Vedomosti App Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Vedomosti App Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Vedomosti Web Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Vedomosti Web Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Viber Web Desktop AD │ 0 │ 0 │ 1 │ 520 │ │ │ │ Viber Web Desktop OT │ 0 │ 0 │ 1 │ 520 │ │ │ │ Viber App Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ Viber App Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Viber Web Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ Web Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Whatsapp Web Desktop │ 0 │ 0 │ 1 │ 520 │ │ │ │ Whatsapp Web Desktop │ 0 │ 0 │ 1 │ 520 │ │ │ │ Whatsapp App Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Whatsapp App Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Whatsapp Web Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Whatsapp Web Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Wildberries Web Desk │ 0 │ 0 │ 1 │ 520 │ │ │ │ Wildberries Web Desk │ 0 │ 0 │ 1 │ 520 │ │ │ │ Wildberries App Mobi │ 0 │ 0 │ 1 │ 520 │ │ │ │ Wildberries App Mobi │ 0 │ 0 │ 1 │ 520 │ │ │ │ Wildberries Web Mobi │ 0 │ 0 │ 1 │ 520 │ │ │ │ Wildberries Web Mobi │ 0 │ 0 │ 1 │ 520 │ │ │ │ Youtube Web Desktop │ 0 │ 0 │ 1 │ 520 │ │ │ │ Youtube Web Desktop │ 0 │ 0 │ 1 │ 520 │ │ │ │ Youtube App Mobile A │ 0 │ 0 │ 1 │ 520 │ │ │ │ Youtube App Mobile O │ 0 │ 0 │ 1 │ 520 │ │ │ │ Youtube Web Mobile A │ 0 │ 0 │ 1 │ 520 │ │ │ │ Youtube Web Mobile O │ 0 │ 0 │ 1 │ 520 │ │ │ │ ВКонтакте Web Deskto │ 0 │ 0 │ 1 │ 520 │ │ │ │ ВКонтакте Web Deskto │ 0 │ 0 │ 1 │ 520 │ │ │ │ ВКонтакте App Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ ВКонтакте App Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ ВКонтакте Web Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ ВКонтакте Web Mobile │ 0 │ 0 │ 1 │ 520 │ │ │ │ Дзен Web Desktop ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ Дзен Web Desktop OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Дзен App Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ Дзен App Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Дзен Web Mobile ADR │ 0 │ 0 │ 1 │ 520 │ │ │ │ Дзен Web Mobile OTS │ 0 │ 0 │ 1 │ 520 │ │ │ │ Лента: Lenta Web Des │ 0 │ 0 │ 1 │ 520 │ │ │ │ Лента: Lenta Web Des │ 0 │ 0 │ 1 │ 520 │ │ │ │ Лента: Lenta App Mob │ 0 │ 0 │ 1 │ 520 │ │ │ │ Лента: Lenta App Mob │ 0 │ 0 │ 1 │ 520 │ │ │ │ Лента: Lenta Web Mob │ 0 │ 0 │ 1 │ 520 │ │ │ │ Лента: Lenta Web Mob │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Картинки Web │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Картинки Web │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Картинки App │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Картинки App │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Картинки Web │ 0 │ 0 │ 1 │ 520 │ │ │ │ Unnamed: 138 │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Карты Web Des │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Карты Web Des │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Карты App Mob │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Карты App Mob │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Карты Web Mob │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Карты Web Mob │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Новости Web D │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Новости Web D │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Новости App M │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Новости App M │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Новости Web M │ 0 │ 0 │ 1 │ 520 │ │ │ │ Яндекс.Новости Web M │ 0 │ 0 │ 1 │ 520 │ │ │ └───────────────────────────────────────┴───────┴───────────┴──────────────────────────┴─────────────────────┘ │ ╰────────────────────────────────────────────────────── End ──────────────────────────────────────────────────────╯
| Date | 2gis Web Desktop ADR | 2gis Web Desktop OTS | 2 gis App Mobile ADR | 2gis App Mobile OTS | 2gis Web Mobile ADR | 2gis Web Mobile OTS | Discord Web Desktop ADR | Discord Web Desktop OTS | Discord App Mobile ADR | Discord App Mobile OTS | Discord Web Mobile ADR | Discord Web Mobile OTS | Facebook Web Desktop ADR | Facebook Web Desktop OTS | Facebook App Mobile ADR | Facebook App Mobile OTS | Facebook Web Mobile ADR | Facebook Web Mobile OTS | Google Карты Web Desktop ADR | Google Карты Web Desktop OTS | Google Карты App Mobile ADR | Google Карты App Mobile OTS | Google Карты Web Mobile ADR | Google Карты Web Mobile OTS | ... | Лента: Lenta Web Desktop ADR | Лента: Lenta Web Desktop OTS | Лента: Lenta App Mobile ADR | Лента: Lenta App Mobile OTS | Лента: Lenta Web Mobile ADR | Лента: Lenta Web Mobile OTS | Яндекс.Картинки Web Desktop ADR | Яндекс.Картинки Web Desktop OTS | Яндекс.Картинки App Mobile ADR | Яндекс.Картинки App Mobile OTS | Яндекс.Картинки Web Mobile ADR | Unnamed: 138 | Яндекс.Карты Web Desktop ADR | Яндекс.Карты Web Desktop OTS | Яндекс.Карты App Mobile ADR | Яндекс.Карты App Mobile OTS | Яндекс.Карты Web Mobile ADR | Яндекс.Карты Web Mobile OTS | Яндекс.Новости Web Desktop ADR | Яндекс.Новости Web Desktop OTS | Яндекс.Новости App Mobile ADR | Яндекс.Новости App Mobile OTS | Яндекс.Новости Web Mobile ADR | Яндекс.Новости Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 01.04.2023 | 342 700 | 6 001 700 | 4 202 800 | 18 459 400 | 508 300 | 3 090 200 | 356 300 | 6 981 600 | 2 473 900 | 22 467 600 | 194 700 | 806 700 | 176 200 | 2 429 500 | 912 100 | 3 793 300 | 849 100 | 3 479 600 | 314 000 | 12 908 500 | 3 133 300 | 10 567 400 | 99 600 | 873 000 | ... | 81 700 | 812 300 | 773 500 | 1 749 900 | 188 800 | 895 400 | 3 518 900 | 84 999 100 | NULL | NULL | 2 575 700 | 37 545 400 | 1 208 200 | 37 678 300 | 7 296 100 | 35 111 800 | 503 400 | 10 393 700 | 3 200 | 3 200 | NULL | NULL | NULL | NULL | 0 |
| 1 | 02.04.2023 | 336 600 | 4 934 100 | 3 991 600 | 16 626 300 | 483 800 | 3 513 800 | 390 500 | 7 053 900 | 2 657 300 | 26 413 000 | 115 100 | 247 000 | 184 200 | 3 649 100 | 786 100 | 3 105 800 | 846 500 | 2 112 200 | 278 500 | 12 065 600 | 2 873 700 | 8 038 400 | 85 000 | 465 700 | ... | 103 300 | 1 112 500 | 859 500 | 2 012 400 | 174 400 | 853 100 | 4 052 800 | 103 989 100 | NULL | NULL | 2 413 800 | 36 294 100 | 1 262 700 | 32 853 000 | 6 726 200 | 29 251 100 | 424 700 | 9 533 000 | 2 500 | 2 500 | NULL | NULL | 20 200 | 23 000 | 0 |
| 2 | 03.04.2023 | 564 000 | 8 679 700 | 4 486 600 | 18 359 400 | 615 400 | 4 214 800 | 250 200 | 3 152 100 | 2 390 500 | 21 673 900 | 146 200 | 390 700 | 213 300 | 2 885 400 | 948 700 | 2 762 800 | 802 700 | 1 370 100 | 421 200 | 16 549 500 | 3 138 700 | 9 651 600 | 83 100 | 946 600 | ... | 57 600 | 607 000 | 945 300 | 2 174 100 | 167 700 | 681 200 | 4 198 400 | 100 130 300 | NULL | NULL | 2 514 100 | 36 161 900 | 1 862 100 | 54 262 200 | 8 041 000 | 42 243 400 | 436 200 | 11 712 100 | NULL | NULL | NULL | NULL | 4 800 | 8 600 | 0 |
3 rows × 152 columns
Количество дубликатов: 0 Полное количество пропущенных значений по всем признакам: 0
Сформируем список признаков:
Для удобства работы упакуем имена признаков к словарь.
list_of_keys = ['Telegram', 'ВКонтакте', 'Дзен']
dict_columns = {}
list_columns = df_dro_full.columns[1:-1]# Убрали Date и age
for num in range(0, len(list_columns), 6):
key_dict = list_columns[num].split()[0]
if key_dict in list_of_keys:
list_3col = []
for i in range(6):
list_3col.append(" ".join(list_columns[num+i].split()[1:]))
dict_columns[key_dict] = list_3col
dict_columns
{'Telegram': ['Web Desktop ADR',
'Web Desktop OTS',
'App Mobile ADR',
'App Mobile OTS',
'Web Mobile ADR',
'Web Mobile OTS'],
'ВКонтакте': ['Web Desktop ADR',
'Web Desktop OTS',
'App Mobile ADR',
'App Mobile OTS',
'Web Mobile ADR',
'Web Mobile OTS'],
'Дзен': ['Web Desktop ADR',
'Web Desktop OTS',
'App Mobile ADR',
'App Mobile OTS',
'Web Mobile ADR',
'Web Mobile OTS']}
list_features = []
list_features.append('Date')
for key, val in dict_columns.items():
for v in val:
list_features.append(key+' '+v)
list_features.append('age')
df_dro = df_dro_full[list_features]
df_dro.head(3)
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 01.04.2023 | 1 106 100 | 7 528 100 | 48 002 300 | 874 501 000 | 130 900 | 1 156 200 | 10 189 900 | 408 502 300 | 46 387 900 | 653 767 100 | 12 212 000 | 101 074 900 | 6 748 000 | 71 520 200 | 1 488 800 | 7 057 000 | 25 731 400 | 374 240 500 | 0 |
| 1 | 02.04.2023 | 1 226 100 | 7 346 200 | 48 408 700 | 866 000 700 | 220 100 | 491 400 | 11 070 600 | 453 913 400 | 45 513 200 | 618 330 800 | 11 236 900 | 90 903 700 | 7 289 900 | 71 918 700 | 1 626 100 | 8 244 900 | 26 125 100 | 385 715 000 | 0 |
| 2 | 03.04.2023 | 1 490 700 | 11 033 500 | 50 368 300 | 1 003 258 000 | 214 000 | 608 400 | 11 878 800 | 536 431 100 | 46 211 900 | 703 643 700 | 12 097 600 | 105 367 000 | 7 845 400 | 90 200 000 | 1 525 100 | 8 607 200 | 27 002 500 | 393 412 700 | 0 |
Отмечаем:
age имеют тип string. Необходимы преобразования типов:Date перевести в тип datetime.# Уберём пробелы в начале и в конце признака 'Data':
df_dro['Date'] = df_dro['Date'].replace(r"^ +| +$", r"", regex=True)
df_dro['Date'] = pd.to_datetime(df_dro.Date, format='%d.%m.%Y')
df_dro.info()
print('Для проведения исследования данные собраны в период с',
df_dro.Date.min(), 'по ', df_dro.Date.max())
<class 'pandas.core.frame.DataFrame'> RangeIndex: 516 entries, 0 to 515 Data columns (total 20 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Date 516 non-null datetime64[ns] 1 Telegram Web Desktop ADR 516 non-null object 2 Telegram Web Desktop OTS 516 non-null object 3 Telegram App Mobile ADR 516 non-null object 4 Telegram App Mobile OTS 516 non-null object 5 Telegram Web Mobile ADR 516 non-null object 6 Telegram Web Mobile OTS 516 non-null object 7 ВКонтакте Web Desktop ADR 516 non-null object 8 ВКонтакте Web Desktop OTS 516 non-null object 9 ВКонтакте App Mobile ADR 516 non-null object 10 ВКонтакте App Mobile OTS 516 non-null object 11 ВКонтакте Web Mobile ADR 516 non-null object 12 ВКонтакте Web Mobile OTS 516 non-null object 13 Дзен Web Desktop ADR 516 non-null object 14 Дзен Web Desktop OTS 516 non-null object 15 Дзен App Mobile ADR 516 non-null object 16 Дзен App Mobile OTS 516 non-null object 17 Дзен Web Mobile ADR 516 non-null object 18 Дзен Web Mobile OTS 516 non-null object 19 age 516 non-null int64 dtypes: datetime64[ns](1), int64(1), object(18) memory usage: 80.8+ KB Для проведения исследования данные собраны в период с 2023-04-01 00:00:00 по 2023-06-25 00:00:00
list_features = df_dro.columns[1:-1] # Сразу уберём Date и age.
list_features
Index(['Telegram Web Desktop ADR', 'Telegram Web Desktop OTS',
'Telegram App Mobile ADR', 'Telegram App Mobile OTS',
'Telegram Web Mobile ADR', 'Telegram Web Mobile OTS',
'ВКонтакте Web Desktop ADR', 'ВКонтакте Web Desktop OTS',
'ВКонтакте App Mobile ADR', 'ВКонтакте App Mobile OTS',
'ВКонтакте Web Mobile ADR', 'ВКонтакте Web Mobile OTS',
'Дзен Web Desktop ADR', 'Дзен Web Desktop OTS', 'Дзен App Mobile ADR',
'Дзен App Mobile OTS', 'Дзен Web Mobile ADR', 'Дзен Web Mobile OTS'],
dtype='object')
# Уберём пробелы в начале и в конце информационных признаках:
df_dro[list_features] = df_dro[list_features].replace(r"^ +| +$", r"", regex=True)
# Уберём пробелы в середине признаков':
df_dro[list_features] = df_dro[list_features].replace(r'\s+', '', regex=True)
# df_dro[list_features] = df_dro[list_features].str.strip().replace(r'\s+',' ', regex=True)
fea_object_float = {}
for fea in list_features:
fea_object_float[fea] = 'float'
df_dro = df_dro.astype(fea_object_float)
view_skim_df(df_dro)
╭──────────────────────────────────────────────── skimpy summary ─────────────────────────────────────────────────╮ │ Data Summary Data Types │ │ ┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┓ ┏━━━━━━━━━━━━━┳━━━━━━━┓ │ │ ┃ dataframe ┃ Values ┃ ┃ Column Type ┃ Count ┃ │ │ ┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━┩ ┡━━━━━━━━━━━━━╇━━━━━━━┩ │ │ │ Number of rows │ 516 │ │ float64 │ 18 │ │ │ │ Number of columns │ 20 │ │ datetime64 │ 1 │ │ │ └───────────────────┴────────┘ │ int32 │ 1 │ │ │ └─────────────┴───────┘ │ │ number │ │ ┏━━━━━━━━━━━━━━━━┳━━━━┳━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━┓ │ │ ┃ column_name ┃ NA ┃ NA % ┃ mean ┃ sd ┃ p0 ┃ p25 ┃ p75 ┃ p100 ┃ hist ┃ │ │ ┡━━━━━━━━━━━━━━━━╇━━━━╇━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━┩ │ │ │ Telegram Web │ 0 │ 0 │ 470000 │ 470000 │ 56000 │ 150000 │ 660000 │ 1900000 │ █▁▁▁▁ │ │ │ │ Desktop │ │ │ │ │ │ │ │ │ │ │ │ │ Telegram Web │ 0 │ 0 │ 3700000 │ 3600000 │ 210000 │ 1000000 │ 4200000 │ 15000000 │ █▅▁▁▁▁ │ │ │ │ Desktop │ │ │ │ │ │ │ │ │ │ │ │ │ Telegram App │ 0 │ 0 │ 17000000 │ 15000000 │ 7100000 │ 8500000 │ 13000000 │ 55000000 │ █ ▂ │ │ │ │ Mobile │ │ │ │ │ │ │ │ │ │ │ │ │ Telegram App │ 0 │ 0 │ 320000000 │ 320000000 │ 66000000 │ 97000000 │ 450000000 │ 1400000000 │ █▂ ▁▁ │ │ │ │ Mobile │ │ │ │ │ │ │ │ │ │ │ │ │ Telegram Web │ 0 │ 0 │ 56000 │ 57000 │ 700 │ 22000 │ 60000 │ 320000 │ █▁▁▁ │ │ │ │ Mobile │ │ │ │ │ │ │ │ │ │ │ │ │ Telegram Web │ 0 │ 0 │ 260000 │ 710000 │ 3800 │ 57000 │ 240000 │ 13000000 │ █ │ │ │ │ Mobile │ │ │ │ │ │ │ │ │ │ │ │ │ ВКонтакте Web │ 0 │ 0 │ 3500000 │ 3300000 │ 1100000 │ 1600000 │ 3500000 │ 12000000 │ █▂ ▁▁ │ │ │ │ Deskto │ │ │ │ │ │ │ │ │ │ │ │ │ ВКонтакте Web │ 0 │ 0 │ 140000000 │ 140000000 │ 23000000 │ 48000000 │ 170000000 │ 540000000 │ █▂ ▁▁ │ │ │ │ Deskto │ │ │ │ │ │ │ │ │ │ │ │ │ ВКонтакте App │ 0 │ 0 │ 15000000 │ 14000000 │ 5300000 │ 6500000 │ 12000000 │ 47000000 │ █ ▂ │ │ │ │ Mobile │ │ │ │ │ │ │ │ │ │ │ │ │ ВКонтакте App │ 0 │ 0 │ 220000000 │ 210000000 │ 42000000 │ 63000000 │ 260000000 │ 720000000 │ █▄▁ ▂ │ │ │ │ Mobile │ │ │ │ │ │ │ │ │ │ │ │ │ ВКонтакте Web │ 0 │ 0 │ 3700000 │ 3400000 │ 1300000 │ 1800000 │ 2800000 │ 12000000 │ █ ▁ │ │ │ │ Mobile │ │ │ │ │ │ │ │ │ │ │ │ │ ВКонтакте Web │ 0 │ 0 │ 34000000 │ 32000000 │ 6900000 │ 12000000 │ 32000000 │ 120000000 │ █▅ ▁▁ │ │ │ │ Mobile │ │ │ │ │ │ │ │ │ │ │ │ │ Дзен Web │ 0 │ 0 │ 2500000 │ 2400000 │ 310000 │ 870000 │ 3000000 │ 9100000 │ █▃ ▁▁ │ │ │ │ Desktop ADR │ │ │ │ │ │ │ │ │ │ │ │ │ Дзен Web │ 0 │ 0 │ 26000000 │ 27000000 │ 690000 │ 5600000 │ 41000000 │ 99000000 │ █▁▂ ▁▁ │ │ │ │ Desktop OTS │ │ │ │ │ │ │ │ │ │ │ │ │ Дзен App │ 0 │ 0 │ 500000 │ 500000 │ 31000 │ 120000 │ 760000 │ 1700000 │ █▁▂ ▁▁ │ │ │ │ Mobile ADR │ │ │ │ │ │ │ │ │ │ │ │ │ Дзен App │ 0 │ 0 │ 2600000 │ 2700000 │ 67000 │ 440000 │ 4000000 │ 9800000 │ █▂▂ ▂▁ │ │ │ │ Mobile OTS │ │ │ │ │ │ │ │ │ │ │ │ │ Дзен Web │ 0 │ 0 │ 8700000 │ 7900000 │ 2700000 │ 4100000 │ 8000000 │ 28000000 │ █▂ ▂ │ │ │ │ Mobile ADR │ │ │ │ │ │ │ │ │ │ │ │ │ Дзен Web │ 0 │ 0 │ 130000000 │ 130000000 │ 18000000 │ 40000000 │ 170000000 │ 580000000 │ █▂ ▁▁ │ │ │ │ Mobile OTS │ │ │ │ │ │ │ │ │ │ │ │ │ age │ 0 │ 0 │ 29 │ 19 │ 0 │ 12 │ 45 │ 55 │ ██████ │ │ │ └────────────────┴────┴──────┴───────────┴───────────┴──────────┴──────────┴───────────┴────────────┴────────┘ │ │ datetime │ │ ┏━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ │ │ ┃ column_name ┃ NA ┃ NA % ┃ first ┃ last ┃ frequency ┃ │ │ ┡━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ │ │ │ Date │ 0 │ 0 │ 2023-04-01 │ 2023-06-25 │ None │ │ │ └────────────────────────┴────────┴───────────┴─────────────────────┴─────────────────────┴──────────────────┘ │ ╰────────────────────────────────────────────────────── End ──────────────────────────────────────────────────────╯
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2023-04-01 | 1106100 | 7528100 | 48002300 | 874501000 | 130900 | 1156200 | 10189900 | 408502300 | 46387900 | 653767100 | 12212000 | 101074900 | 6748000 | 71520200 | 1488800 | 7057000 | 25731400 | 374240500 | 0 |
| 1 | 2023-04-02 | 1226100 | 7346200 | 48408700 | 866000700 | 220100 | 491400 | 11070600 | 453913400 | 45513200 | 618330800 | 11236900 | 90903700 | 7289900 | 71918700 | 1626100 | 8244900 | 26125100 | 385715000 | 0 |
| 2 | 2023-04-03 | 1490700 | 11033500 | 50368300 | 1003258000 | 214000 | 608400 | 11878800 | 536431100 | 46211900 | 703643700 | 12097600 | 105367000 | 7845400 | 90200000 | 1525100 | 8607200 | 27002500 | 393412700 | 0 |
Количество дубликатов: 0 Полное количество пропущенных значений по всем признакам: 0
df_dro = df_dro.sort_values(by=['Date', 'age'])
df_dro.head(7)
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2023-04-01 | 1106100 | 7528100 | 48002300 | 874501000 | 130900 | 1156200 | 10189900 | 408502300 | 46387900 | 653767100 | 12212000 | 101074900 | 6748000 | 71520200 | 1488800 | 7057000 | 25731400 | 374240500 | 0 |
| 86 | 2023-04-01 | 528600 | 2585000 | 12720400 | 418588100 | 46800 | 548900 | 3193500 | 181822300 | 11942700 | 265913900 | 3040800 | 18875000 | 516600 | 920100 | 51300 | 123100 | 3184900 | 26344000 | 12 |
| 172 | 2023-04-01 | 193700 | 1580700 | 9500400 | 152031300 | 13800 | 142800 | 2158300 | 86720800 | 11254700 | 169693700 | 2760800 | 25939400 | 814300 | 5594400 | 121200 | 420500 | 4145600 | 38556800 | 25 |
| 258 | 2023-04-01 | 174100 | 2125100 | 10720000 | 146072600 | 27600 | 125600 | 1729300 | 58916700 | 10485100 | 109884600 | 2651400 | 29713000 | 1284300 | 13998800 | 240600 | 1469400 | 5718700 | 73913900 | 35 |
| 344 | 2023-04-01 | 106100 | 808700 | 7151500 | 85224000 | 27700 | 277300 | 1368200 | 42561700 | 6481300 | 60018000 | 1588500 | 13024200 | 1383400 | 13333300 | 292600 | 1271900 | 4815500 | 74602000 | 45 |
| 430 | 2023-04-01 | 103600 | 428600 | 7910000 | 72585000 | 15000 | 61600 | 1740600 | 38480800 | 6224100 | 48256900 | 2170500 | 13523300 | 2749400 | 37673600 | 783100 | 3772100 | 7866700 | 160823800 | 55 |
| 1 | 2023-04-02 | 1226100 | 7346200 | 48408700 | 866000700 | 220100 | 491400 | 11070600 | 453913400 | 45513200 | 618330800 | 11236900 | 90903700 | 7289900 | 71918700 | 1626100 | 8244900 | 26125100 | 385715000 | 0 |
Видим, что сначала идут данные от 1 апреля, и затем уже 2 апреля. Сортировка выполнилась.
ADR и OTS по возрастной категории 'до 12 лет'.¶Выделим из полного датафрейма, по всем возрастным группам, те записи, которые соответствуют выбранной возрастной группе.
print("Размер полного датафрейма:", df_dro.shape)
df_dro_0 = df_dro[df_dro.age == 0]
if (df_dro.shape[0] / 6 == df_dro_0.shape[0]):
print("Выделение части датафрейма проведено корректно.")
else:
print("Произошла потеря данных!")
print("Размер датафрейма по возрастной категории 'до 12 лет':",
df_dro_0.shape)
df_dro_0.head(3)
Размер полного датафрейма: (516, 20) Выделение части датафрейма проведено корректно. Размер датафрейма по возрастной категории 'до 12 лет': (86, 20)
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2023-04-01 | 1106100 | 7528100 | 48002300 | 874501000 | 130900 | 1156200 | 10189900 | 408502300 | 46387900 | 653767100 | 12212000 | 101074900 | 6748000 | 71520200 | 1488800 | 7057000 | 25731400 | 374240500 | 0 |
| 1 | 2023-04-02 | 1226100 | 7346200 | 48408700 | 866000700 | 220100 | 491400 | 11070600 | 453913400 | 45513200 | 618330800 | 11236900 | 90903700 | 7289900 | 71918700 | 1626100 | 8244900 | 26125100 | 385715000 | 0 |
| 2 | 2023-04-03 | 1490700 | 11033500 | 50368300 | 1003258000 | 214000 | 608400 | 11878800 | 536431100 | 46211900 | 703643700 | 12097600 | 105367000 | 7845400 | 90200000 | 1525100 | 8607200 | 27002500 | 393412700 | 0 |
ADR и OTS по возрастной категории 'до 12 лет'.¶Создам вспомогательную функцию.
def plot_average_daily_duration(df, key, list_6values):
'''
Функция вывода графиков 'Average Daily Duration'.
'''
fg = plt.figure(figsize=(9, 4), constrained_layout=True)
gs = gridspec.GridSpec(ncols=2, nrows=1, figure=fg)
fig_ax_1 = fg.add_subplot(gs[0, 0])
for i in range(0, 6, 2):
y_title = key + ' ' + list_6values[i]
plt.plot(df['Date'], df[y_title], label=y_title)
plt.xlabel('Дата', color = 'blue')
plt.xticks(fontsize = 8, rotation=45)
plt.ylabel('Average Daily Duration на население',
fontsize = 8, color = 'blue')
plt.legend(bbox_to_anchor=(0.5, 1.3), loc='upper center')
fig_ax_2 = fg.add_subplot(gs[0, 1])
for i in range(1, 6, 2):
y_title = key + ' ' + list_6values[i]
plt.plot(df['Date'], df[y_title], label=y_title)
plt.xlabel('Дата', color = 'blue')
plt.xticks(fontsize = 8, rotation=45)
plt.ylabel('Average Daily Duration на пользователей',
fontsize = 8, color = 'blue')
plt.legend(bbox_to_anchor=(0.5, 1.3), loc='upper center')
plt.show()
print('Количество источников информации:', len(dict_columns))
print('Список источников информации:', list(dict_columns.keys()))
Количество источников информации: 3 Список источников информации: ['Telegram', 'ВКонтакте', 'Дзен']
for k_6col, v_6cols in dict_columns.items():
plot_average_daily_duration(df_dro, k_6col, v_6cols)
Отмечаем, что данные от трех источников имеют разные масштабы:
Так как абсолютные значения нас не интересуют, интересует только поведение измеряемых величин, приведём все значения к одному масштабу.
# Настроим, чтобы числа в датасетах отражались без знаков после запятой
pd.set_option('display.float_format', '{:.0f}'.format)
# Создадим кореж с именами признаков и масштабируемых коэффициентов:
coeff_scale = (
('Telegram Web Desktop ADR', 50), ('Telegram Web Mobile ADR', 200),
('Telegram Web Desktop OTS', 0.5), ('Telegram App Mobile OTS', 0.005),
('ВКонтакте Web Desktop ADR', 4), ('ВКонтакте Web Mobile ADR', 4),
('ВКонтакте Web Mobile OTS', 5), ('Дзен Web Desktop ADR', 4),
('Дзен App Mobile ADR', 15), ('Дзен Web Desktop OTS', 5),
('Дзен App Mobile OTS', 40)
)
# Создадим врЕменный датафрейм
df_dro_0_tmp = df_dro_0.copy()
for i in range(len(coeff_scale)):
df_dro_0_tmp[coeff_scale[i][0]] = df_dro_0_tmp[coeff_scale[i][0]].\
apply(lambda x: x * coeff_scale[i][1])
df_dro_0_tmp.head(3)
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2023-04-01 | 55305000 | 3764050 | 48002300 | 4372505 | 26180000 | 1156200 | 40759600 | 408502300 | 46387900 | 653767100 | 48848000 | 505374500 | 26992000 | 357601000 | 22332000 | 282280000 | 25731400 | 374240500 | 0 |
| 1 | 2023-04-02 | 61305000 | 3673100 | 48408700 | 4330004 | 44020000 | 491400 | 44282400 | 453913400 | 45513200 | 618330800 | 44947600 | 454518500 | 29159600 | 359593500 | 24391500 | 329796000 | 26125100 | 385715000 | 0 |
| 2 | 2023-04-03 | 74535000 | 5516750 | 50368300 | 5016290 | 42800000 | 608400 | 47515200 | 536431100 | 46211900 | 703643700 | 48390400 | 526835000 | 31381600 | 451000000 | 22876500 | 344288000 | 27002500 | 393412700 | 0 |
for key, value in dict_columns.items():
plot_average_daily_duration(df_dro_0_tmp, key, value)
# Удалим ненужный более датафрейм
del df_dro_0_tmp
По выровненным к одному масштабу значеням графикам распределения можно отметить:
def format_my(num):
'''
Функция установки разделительного знака в виде запятой
для больших чисел.
'''
return f"{num:,}"
Используем Ящик с усами для отображения статистической информации о распределении Telegram Web Mobile OTS, такие как медиана, квартили и аномальные значения:
print('Аномальное значение "Telegram Web Mobile OTS":',
format_my(df_dro_0['Telegram Web Mobile OTS'].max()))
fig = plt.figure(figsize = (8,2))
sns.boxplot(df_dro_0['Telegram Web Mobile OTS'])
plt.xlabel("Эначения 'OTS' Telegram Web Mobile", fontsize=10, color='red')
plt.show;
Аномальное значение "Telegram Web Mobile OTS": 12,758,100.0
Отмечаем:
# Выберем исследуемый признак:
tmp = df_dro_0['Telegram Web Mobile OTS']
# Отсотрируем, начиная с максимального по убыванию:
display(tmp.sort_values(ascending = False).head(5))
13 12758100 30 1558600 73 1526800 85 1331800 81 1303600 Name: Telegram Web Mobile OTS, dtype: float64
# Посмотрим строку c индексом 13:
df_dro_0.iloc[[13]]
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 13 | 2023-04-14 | 1318800 | 10517000 | 50814900 | 949349500 | 194200 | 12758100 | 11388500 | 402933100 | 46021100 | 695047100 | 11411700 | 119208600 | 7721200 | 77935600 | 1648000 | 8324600 | 26028500 | 378983600 | 0 |
Отмечаем:
Telegram Web Mobile OTS имеет:Возможно, это ошибка, связанная с ручной записью (ошиблись в количестве знаков до до десятичного знака). Проверить это можно только с исполнителем.
Изучим сезонную (периодическую) составляющую за неделю.
Введём вспомогательные функции.
def volume_seasonal(df_dd, list_columns):
'''
Функция расчёта тренда и отображения сезонности временного ряда.
'''
for num in tqdm(range(0, len(list_columns), 2)):
fg = plt.figure(figsize=(9, 3), constrained_layout=True)
gs = gridspec.GridSpec(ncols=2, nrows=1, figure=fg)
# Создадим датафрейм и выберем для него
# признак 'Date' и один информационнный.
for_decompose = df_dd[['Date', list_columns[num]]]
for_decompose.index = for_decompose['Date']
for_decompose = for_decompose.drop('Date', axis=1)
for_decompose.sort_index(inplace=True)
for_decompose = for_decompose.resample('1D').sum()
decomp = seasonal_decompose(for_decompose)
fig_ax_1 = fg.add_subplot(gs[0, 0])
decomp.seasonal[date_start:date_stop].plot(ax=plt.gca())
plt.title(list_columns[num]+' - ПЕРИОД',
size = 10, color = 'red')
plt.xlabel('Метрика "Average Daily Reach"', color = 'blue')
plt.ylabel('Значение тренда.', color = 'blue');
for_decompose = df_dd[['Date', list_columns[num+1]]]
for_decompose.index = for_decompose['Date']
for_decompose = for_decompose.drop('Date', axis=1)
for_decompose.sort_index(inplace=True)
for_decompose = for_decompose.resample('1D').sum()
decomp = seasonal_decompose(for_decompose)
fig_ax_2 = fg.add_subplot(gs[0, 1])
decomp.seasonal[date_start:date_stop].plot(ax=plt.gca())
plt.title(list_columns[num+1]+' - ПЕРИОД.',
size = 10, color = 'red')
plt.xlabel('Метрика "Opportunity To See"', color = 'blue')
plt.ylabel('Значение периодическое.', color = 'blue');
plt.tight_layout()
def calc_print_weekday(date_start, date_stop):
'''
Функция нахождения названий дней недели.
'''
date_tmp = datetime.strptime(date_start, '%Y-%m-%d')
date_end = datetime.strptime(date_stop, '%Y-%m-%d')
labels = []
while date_tmp <= date_end:
labels.append(str(date_tmp.strftime('%y-%m-%d')) + \
' - ' + date_tmp.strftime('%a'))
date_tmp = date_tmp + timedelta(days=1)
print('Дни недели:')
n = 0
for lab in labels:
if n < 3:
print(lab, 10*' ', end='')
n = n + 1
else:
print(lab, end='\n')
n = 0
date_start, date_stop = '2023-04-01', '2023-04-16'
calc_print_weekday(date_start, date_stop)
volume_seasonal(df_dro_0, list_features)
Дни недели: 23-04-01 - Sat 23-04-02 - Sun 23-04-03 - Mon 23-04-04 - Tue 23-04-05 - Wed 23-04-06 - Thu 23-04-07 - Fri 23-04-08 - Sat 23-04-09 - Sun 23-04-10 - Mon 23-04-11 - Tue 23-04-12 - Wed 23-04-13 - Thu 23-04-14 - Fri 23-04-15 - Sat 23-04-16 - Sun
0%| | 0/9 [00:00<?, ?it/s]
Отмечаем:
Оценка стационарности временного ряда.
Временной ряд называется стационарным, если он не имеет тренда. Говоря более точно, среднее значение и дисперсия не меняются со смещением во времени.
Оценку стационарности проведём в способами:
визуально,Дики-Фуллера.Создадим вспомогательный функции
def visual_stationarity_1(fg, gs, df, list_columns, num, pos):
'''
Функция построения 'скользящего среднего' единичного графика.
'''
# Зададим временный датафрейм c признаком для рассчитываемых
# тестовых значений скользящего среднего:
df_tmp = df[['Date', list_columns[num+pos], 'age']].copy()
df_tmp = df_tmp.sort_values(by=['Date', 'age'])
df_tmp = df_tmp.groupby(['Date']).sum()[[list_columns[num+pos]]]
df_tmp['mean'] = (df_tmp[list_columns[num+pos]].
rolling(window = WINDOW_STATIONARITY).
mean() )
fig_ax_1 = fg.add_subplot(gs[0, 0+pos])
plt.plot(df_tmp[list_columns[num+pos]],
label = 'Кол-во контактов по дням', color = 'steelblue')
plt.plot(df_tmp['mean'],
label = 'Скользящее среднее за неделю', color = 'orange')
plt.legend(title = 'Графики:', loc = 'upper left')
plt.xticks(fontsize = 8, rotation=15)
plt.ylabel('Кол-во контактов.', color = 'blue')
plt.title(list_columns[num+pos], color = 'red')
def visual_stationarity_6(df, list_columns):
'''
Функция построения 'скользящего среднего' 6-и графиков.
'''
for num in tqdm(range(0, len(list_columns), 2)):
fg = plt.figure(figsize=(9, 3), constrained_layout=True)
gs = gridspec.GridSpec(ncols=2, nrows=1, figure=fg)
visual_stationarity_1(fg, gs, df, list_columns, num, 0)
visual_stationarity_1(fg, gs, df, list_columns, num, 1)
plt.tight_layout()
visual_stationarity_6(df_dro_0, list_features)
0%| | 0/9 [00:00<?, ?it/s]
Отмечаем:
Тест Дики-Фуллера (Dickey-Fuller test).
Тест заключается в том, что нужно выполнить статистическую проверку следующей гипотезы:
Используем пороговое значение, равное 0.05 (5%).
# Настроим, чтобы числа в датасетах отражались с 3 знаками после запятой
pd.set_option('display.float_format', '{:.3f}'.format)
df_test_DF = pd.DataFrame(columns=[
'source', 'ADF criterion', 'P-value', 'Critical value 1%',
'Critical values 5%', 'Conclusion'])
def test_DF(df, columns):
'''
Функция проведения теста 'Дики-Фуллера' для проверки стационарности.
'''
for col in columns:
# Передадим функции 'adfuller' данные по изучаемому признаку и
# сохраним результат в переменной adf_test:
adf_test = adfuller(df[col].fillna(0))
if adf_test[0] < adf_test[4]["5%"]:
df_test_DF.loc[len(df_test_DF.index )] =(
[col, adf_test[0], adf_test[1], adf_test[4]["1%"],
adf_test[4]["5%"], "Стационарен."])
else:
df_test_DF.loc[len(df_test_DF.index )] =(
[col, adf_test[0], adf_test[1], adf_test[4]["1%"],
adf_test[4]["5%"],"НЕ стационарен!"])
# adf_test[4]["10%"] - если интересно!
# Запуск исполнения теста
test_DF(df_dro_0, list_features)
# Просмотр датафрейма с результатами
display(df_test_DF)
# Удалим ненужный более датафрейм
del df_test_DF
| source | ADF criterion | P-value | Critical value 1% | Critical values 5% | Conclusion | |
|---|---|---|---|---|---|---|
| 0 | Telegram Web Desktop ADR | -2.103 | 0.243 | -3.518 | -2.900 | НЕ стационарен! |
| 1 | Telegram Web Desktop OTS | -1.388 | 0.588 | -3.523 | -2.902 | НЕ стационарен! |
| 2 | Telegram App Mobile ADR | -0.854 | 0.803 | -3.516 | -2.899 | НЕ стационарен! |
| 3 | Telegram App Mobile OTS | -0.363 | 0.916 | -3.516 | -2.899 | НЕ стационарен! |
| 4 | Telegram Web Mobile ADR | -6.106 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 5 | Telegram Web Mobile OTS | -9.516 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 6 | ВКонтакте Web Desktop ADR | -1.023 | 0.745 | -3.517 | -2.899 | НЕ стационарен! |
| 7 | ВКонтакте Web Desktop OTS | -1.990 | 0.291 | -3.521 | -2.901 | НЕ стационарен! |
| 8 | ВКонтакте App Mobile ADR | -1.930 | 0.318 | -3.516 | -2.899 | НЕ стационарен! |
| 9 | ВКонтакте App Mobile OTS | -0.755 | 0.832 | -3.516 | -2.899 | НЕ стационарен! |
| 10 | ВКонтакте Web Mobile ADR | -1.628 | 0.469 | -3.519 | -2.900 | НЕ стационарен! |
| 11 | ВКонтакте Web Mobile OTS | -7.472 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 12 | Дзен Web Desktop ADR | -1.706 | 0.428 | -3.518 | -2.900 | НЕ стационарен! |
| 13 | Дзен Web Desktop OTS | -2.819 | 0.056 | -3.518 | -2.900 | НЕ стационарен! |
| 14 | Дзен App Mobile ADR | -7.275 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 15 | Дзен App Mobile OTS | -5.877 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 16 | Дзен Web Mobile ADR | -5.813 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 17 | Дзен Web Mobile OTS | -5.679 | 0.000 | -3.510 | -2.896 | Стационарен. |
Промежуточные выводы для всех источников 'Telegram', 'ВКонтакте', 'Дзен' по возрастной группе до 12 лет:
# уберем из памяти ненужный более датафрейм.
del df_dro_0
ADR и OTS по возрастной категории 'от 12 до 24 лет'.¶Выделим из полного датафрейма, по всем возрастным группам, те записи, которые соответствуют выбранной возрастной группе.
print("Размер полного датафрейма:", df_dro.shape)
df_dro_12 = df_dro[df_dro.age == 12]
if (df_dro.shape[0] / 6 == df_dro_12.shape[0]):
print("Выделение части датафрейма проведено корректно.")
else:
print("Произошла потеря данных!")
print("Размер датафрейма по возрастной категории 'от 12 до 24 лет':",
df_dro_12.shape)
df_dro_12.head(3)
Размер полного датафрейма: (516, 20) Выделение части датафрейма проведено корректно. Размер датафрейма по возрастной категории 'от 12 до 24 лет': (86, 20)
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 86 | 2023-04-01 | 528600.000 | 2585000.000 | 12720400.000 | 418588100.000 | 46800.000 | 548900.000 | 3193500.000 | 181822300.000 | 11942700.000 | 265913900.000 | 3040800.000 | 18875000.000 | 516600.000 | 920100.000 | 51300.000 | 123100.000 | 3184900.000 | 26344000.000 | 12 |
| 87 | 2023-04-02 | 565900.000 | 2138000.000 | 12625100.000 | 408794600.000 | 63500.000 | 154300.000 | 3620000.000 | 184973600.000 | 11402800.000 | 231775400.000 | 2526400.000 | 13510000.000 | 774000.000 | 1450900.000 | 69800.000 | 187500.000 | 3145400.000 | 24081400.000 | 12 |
| 88 | 2023-04-03 | 623600.000 | 2961700.000 | 13278800.000 | 480018400.000 | 55700.000 | 165400.000 | 3537900.000 | 236584900.000 | 11901100.000 | 286711900.000 | 3054900.000 | 22011000.000 | 425700.000 | 1108700.000 | 39200.000 | 112400.000 | 3273900.000 | 26768000.000 | 12 |
ADR и OTS по возрастной категории 'до 12 лет'.¶for key, value in dict_columns.items():
plot_average_daily_duration(df_dro_12, key, value)
Отмечаем, что данные от трех источников имеют разные масштабы:
Так как абсолютные значения нас не интересуют, интересует только поведение измеряемых величин, приведём все значения к одному масштабу.
# Создадим кореж с именами признаков и масштабируемых коэффициентов:
coeff_scale = (
('Telegram Web Desktop ADR', 50), ('Telegram Web Mobile ADR', 200),
('Telegram Web Desktop OTS', 0.5), ('Telegram App Mobile OTS', 0.005),
('ВКонтакте Web Desktop ADR', 4), ('ВКонтакте Web Mobile ADR', 4),
('ВКонтакте Web Mobile OTS', 5), ('Дзен Web Desktop ADR', 4),
('Дзен App Mobile ADR', 15), ('Дзен Web Desktop OTS', 5),
('Дзен App Mobile OTS', 40)
)
# Создадим врЕменный датафрейм
df_dro_12_tmp = df_dro_12.copy()
for i in range(len(coeff_scale)):
df_dro_12_tmp[coeff_scale[i][0]] = df_dro_12_tmp[coeff_scale[i][0]].\
apply(lambda x: x * coeff_scale[i][1])
df_dro_12_tmp.head(3)
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 86 | 2023-04-01 | 26430000.000 | 1292500.000 | 12720400.000 | 2092940.500 | 9360000.000 | 548900.000 | 12774000.000 | 181822300.000 | 11942700.000 | 265913900.000 | 12163200.000 | 94375000.000 | 2066400.000 | 4600500.000 | 769500.000 | 4924000.000 | 3184900.000 | 26344000.000 | 12 |
| 87 | 2023-04-02 | 28295000.000 | 1069000.000 | 12625100.000 | 2043973.000 | 12700000.000 | 154300.000 | 14480000.000 | 184973600.000 | 11402800.000 | 231775400.000 | 10105600.000 | 67550000.000 | 3096000.000 | 7254500.000 | 1047000.000 | 7500000.000 | 3145400.000 | 24081400.000 | 12 |
| 88 | 2023-04-03 | 31180000.000 | 1480850.000 | 13278800.000 | 2400092.000 | 11140000.000 | 165400.000 | 14151600.000 | 236584900.000 | 11901100.000 | 286711900.000 | 12219600.000 | 110055000.000 | 1702800.000 | 5543500.000 | 588000.000 | 4496000.000 | 3273900.000 | 26768000.000 | 12 |
for key, value in dict_columns.items():
plot_average_daily_duration(df_dro_12_tmp, key, value)
# Удалим ненужный более датафрейм
del df_dro_12_tmp
По выровненным к одному масштабу значеням графикам распределения можно отметить:
Используем Ящик с усами для отображения статистической информации о распределении Telegram Web Mobile OTS, такие как медиана, квартили и аномальные значения:
print('Аномальное значение "Telegram Web Mobile OTS":',
format_my(df_dro_12['Telegram Web Mobile OTS'].max()))
fig = plt.figure(figsize = (8,2))
sns.boxplot(df_dro_12['Telegram Web Mobile OTS'])
plt.xlabel("Эначения 'OTS' Telegram Web Mobile", fontsize=10, color='red')
plt.show;
Аномальное значение "Telegram Web Mobile OTS": 5,095,300.0
Отмечаем:
# Выберем исследуемый признак:
tmp = df_dro_12['Telegram Web Mobile OTS']
# Отсотрируем, начиная с максимального по убыванию:
display(tmp.sort_values(ascending = False).head(7))
99 5095300.000 159 1220800.000 104 999400.000 153 922300.000 167 877800.000 171 872200.000 116 820400.000 Name: Telegram Web Mobile OTS, dtype: float64
# Посмотрим строку c индексом 99 и 159 с учётом того, что выше в
# общем датасете есть 86 записей для детей до 12 лет:
df_dro_12.iloc[[99-86, 159-86]]
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 99 | 2023-04-14 | 481500.000 | 4296500.000 | 12977000.000 | 426793800.000 | 39200.000 | 5095300.000 | 3644600.000 | 181044800.000 | 11801800.000 | 283361400.000 | 2943400.000 | 22242900.000 | 606100.000 | 1294600.000 | 110800.000 | 261400.000 | 3190900.000 | 24913100.000 | 12 |
| 159 | 2023-06-13 | 879500.000 | 5058000.000 | 13482600.000 | 487059500.000 | 53300.000 | 1220800.000 | 3497400.000 | 190227200.000 | 11536900.000 | 256124000.000 | 2536700.000 | 20314500.000 | 658400.000 | 1659200.000 | 73800.000 | 368200.000 | 2918900.000 | 22883700.000 | 12 |
Отмечаем:
Telegram Web Mobile OTS имеет ту же дату регистрации 14 апреля 2023, как и в выборке для детей до 12 лет!.Изучим сезонную (периодическую) составляющую за неделю.
date_start, date_stop = '2023-04-01', '2023-04-16'
calc_print_weekday(date_start, date_stop)
volume_seasonal(df_dro_12, list_features)
Дни недели: 23-04-01 - Sat 23-04-02 - Sun 23-04-03 - Mon 23-04-04 - Tue 23-04-05 - Wed 23-04-06 - Thu 23-04-07 - Fri 23-04-08 - Sat 23-04-09 - Sun 23-04-10 - Mon 23-04-11 - Tue 23-04-12 - Wed 23-04-13 - Thu 23-04-14 - Fri 23-04-15 - Sat 23-04-16 - Sun
0%| | 0/9 [00:00<?, ?it/s]
Отмечаем:
Оценка стационарности временного ряда.
Временной ряд называется стационарным, если он не имеет тренда.
Оценку стационарности проведём в способами:
визуально,Дики-Фуллера.visual_stationarity_6(df_dro_12, list_features)
0%| | 0/9 [00:00<?, ?it/s]
Отмечаем:
Тест Дики-Фуллера (Dickey-Fuller test).
Тест заключается в том, что нужно выполнить статистическую проверку следующей гипотезы:
Используем пороговое значение, равное 0.05 (5%)
# Настроим, чтобы числа в датасетах отражались с 3 знаками после запятой
pd.set_option('display.float_format', '{:.3f}'.format)
df_test_DF = pd.DataFrame(columns=[
'source', 'ADF criterion', 'P-value', 'Critical value 1%',
'Critical values 5%', 'Conclusion'])
# Запуск исполнения теста
test_DF(df_dro_12, list_features)
# Просмотр датафрейма с результатами
display(df_test_DF)
# Удалим ненужный более датафрейм
del df_test_DF
| source | ADF criterion | P-value | Critical value 1% | Critical values 5% | Conclusion | |
|---|---|---|---|---|---|---|
| 0 | Telegram Web Desktop ADR | -1.690 | 0.436 | -3.517 | -2.899 | НЕ стационарен! |
| 1 | Telegram Web Desktop OTS | -7.397 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 2 | Telegram App Mobile ADR | -1.083 | 0.722 | -3.523 | -2.902 | НЕ стационарен! |
| 3 | Telegram App Mobile OTS | -1.234 | 0.659 | -3.516 | -2.899 | НЕ стационарен! |
| 4 | Telegram Web Mobile ADR | -7.180 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 5 | Telegram Web Mobile OTS | -9.107 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 6 | ВКонтакте Web Desktop ADR | -1.194 | 0.676 | -3.518 | -2.900 | НЕ стационарен! |
| 7 | ВКонтакте Web Desktop OTS | -2.503 | 0.115 | -3.518 | -2.900 | НЕ стационарен! |
| 8 | ВКонтакте App Mobile ADR | 0.374 | 0.980 | -3.517 | -2.899 | НЕ стационарен! |
| 9 | ВКонтакте App Mobile OTS | 0.007 | 0.959 | -3.516 | -2.899 | НЕ стационарен! |
| 10 | ВКонтакте Web Mobile ADR | -0.936 | 0.776 | -3.516 | -2.899 | НЕ стационарен! |
| 11 | ВКонтакте Web Mobile OTS | -6.707 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 12 | Дзен Web Desktop ADR | -4.314 | 0.000 | -3.511 | -2.897 | Стационарен. |
| 13 | Дзен Web Desktop OTS | -1.144 | 0.697 | -3.516 | -2.899 | НЕ стационарен! |
| 14 | Дзен App Mobile ADR | -8.939 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 15 | Дзен App Mobile OTS | -5.988 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 16 | Дзен Web Mobile ADR | -5.487 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 17 | Дзен Web Mobile OTS | -5.522 | 0.000 | -3.511 | -2.897 | Стационарен. |
Промежуточные выводы для всех источников 'Telegram', 'ВКонтакте', 'Дзен' по возрастной группе от 12 до 24 лет:
# уберем из памяти ненужный более датафрейм.
del df_dro_12
ADR и OTS по возрастной категории 'от 25 до 34 лет'.¶Выделим из полного датафрейма, по всем возрастным группам, те записи, которые соответствуют выбранной возрастной группе.
print("Размер полного датафрейма:", df_dro.shape)
df_dro_24 = df_dro[df_dro.age == 25]
if (df_dro.shape[0] / 6 == df_dro_24.shape[0]):
print("Выделение части датафрейма проведено корректно.")
else:
print("Произошла потеря данных!")
print("Размер датафрейма по возрастной категории 'от 24 до 34 лет':",
df_dro_24.shape)
df_dro_24.head(3)
Размер полного датафрейма: (516, 20) Выделение части датафрейма проведено корректно. Размер датафрейма по возрастной категории 'от 24 до 34 лет': (86, 20)
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 172 | 2023-04-01 | 193700.000 | 1580700.000 | 9500400.000 | 152031300.000 | 13800.000 | 142800.000 | 2158300.000 | 86720800.000 | 11254700.000 | 169693700.000 | 2760800.000 | 25939400.000 | 814300.000 | 5594400.000 | 121200.000 | 420500.000 | 4145600.000 | 38556800.000 | 25 |
| 173 | 2023-04-02 | 209800.000 | 1758000.000 | 9694900.000 | 153232900.000 | 29800.000 | 50400.000 | 2238000.000 | 81633300.000 | 11074900.000 | 161991400.000 | 2649800.000 | 24563800.000 | 860300.000 | 5055000.000 | 104100.000 | 320200.000 | 4290800.000 | 40911000.000 | 25 |
| 174 | 2023-04-03 | 289800.000 | 2752900.000 | 10005700.000 | 173813100.000 | 27200.000 | 99300.000 | 2554700.000 | 109053100.000 | 11093500.000 | 182898400.000 | 2929500.000 | 30113500.000 | 800800.000 | 6045500.000 | 111000.000 | 568400.000 | 4412000.000 | 44273800.000 | 25 |
ADR и OTS по возрастной категории 'от 25 до 34 лет'.¶for key, value in dict_columns.items():
plot_average_daily_duration(df_dro_24, key, value)
Отмечаем, что данные от трех источников имеют разные масштабы:
Так как абсолютные значения нас не интересуют, интересует только поведение измеряемых величин, приведём все значения к одному масштабу.
# Настроим, чтобы числа в датасетах отражались без знаков после запятой
pd.set_option('display.float_format', '{:.0f}'.format)
# Создадим врЕменный датафрейм
df_dro_24_tmp = df_dro_24.copy()
for i in range(len(coeff_scale)):
df_dro_24_tmp[coeff_scale[i][0]] = df_dro_24_tmp[coeff_scale[i][0]].\
apply(lambda x: x * coeff_scale[i][1])
display(df_dro_24_tmp.head(3))
for key, value in dict_columns.items():
plot_average_daily_duration(df_dro_24_tmp, key, value)
# Удалим ненужный более датафрейм
del df_dro_24_tmp
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 172 | 2023-04-01 | 9685000 | 790350 | 9500400 | 760156 | 2760000 | 142800 | 8633200 | 86720800 | 11254700 | 169693700 | 11043200 | 129697000 | 3257200 | 27972000 | 1818000 | 16820000 | 4145600 | 38556800 | 25 |
| 173 | 2023-04-02 | 10490000 | 879000 | 9694900 | 766164 | 5960000 | 50400 | 8952000 | 81633300 | 11074900 | 161991400 | 10599200 | 122819000 | 3441200 | 25275000 | 1561500 | 12808000 | 4290800 | 40911000 | 25 |
| 174 | 2023-04-03 | 14490000 | 1376450 | 10005700 | 869066 | 5440000 | 99300 | 10218800 | 109053100 | 11093500 | 182898400 | 11718000 | 150567500 | 3203200 | 30227500 | 1665000 | 22736000 | 4412000 | 44273800 | 25 |
По выровненным к одному масштабу значеням графикам распределения можно отметить:
Используем Ящик с усами для отображения статистической информации о распределении Telegram Web Mobile OTS, такие как медиана, квартили и аномальные значения:
print('Аномальное значение "Telegram Web Mobile OTS":',
format_my(df_dro_24['Telegram Web Mobile OTS'].max()))
fig = plt.figure(figsize = (8,2))
sns.boxplot(df_dro_24['Telegram Web Mobile OTS'])
plt.xlabel("Эначения 'OTS' Telegram Web Mobile", fontsize=10, color='red')
plt.show;
Аномальное значение "Telegram Web Mobile OTS": 786,400.0
Отмечаем:
# Выберем исследуемый признак:
tmp = df_dro_24['Telegram Web Mobile OTS']
# Отсотрируем, начиная с максимального по убыванию:
display(tmp.sort_values(ascending = False).head(5))
185 786400 180 295500 218 278400 238 265300 204 247900 Name: Telegram Web Mobile OTS, dtype: float64
# Посмотрим строку c индексом 185 с учётом того, что выше в
# общем датасете есть 86 записей для детей 'до 12 лет' и
# 86 записей для группы 'от 12 до 24 лет':
df_dro_24.iloc[[185-86*2]]
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 185 | 2023-04-14 | 250900 | 2346100 | 9998800 | 180436200 | 26400 | 786400 | 2237900 | 78897300 | 11144600 | 179205000 | 2593700 | 38864500 | 870000 | 5297400 | 135200 | 332100 | 3954500 | 37145200 | 25 |
Отмечаем:
Telegram Web Mobile OTS имеет ту же дату регистрации 14 апреля 2023, как и в выборке для детей до 12 лет и для группы 'от 12 до 24 лет!Изучим сезонную (периодическую) составляющую за неделю.
date_start, date_stop = '2023-04-01', '2023-04-16'
calc_print_weekday(date_start, date_stop)
volume_seasonal(df_dro_24, list_features)
Дни недели: 23-04-01 - Sat 23-04-02 - Sun 23-04-03 - Mon 23-04-04 - Tue 23-04-05 - Wed 23-04-06 - Thu 23-04-07 - Fri 23-04-08 - Sat 23-04-09 - Sun 23-04-10 - Mon 23-04-11 - Tue 23-04-12 - Wed 23-04-13 - Thu 23-04-14 - Fri 23-04-15 - Sat 23-04-16 - Sun
0%| | 0/9 [00:00<?, ?it/s]
Отмечаем:
Оценка стационарности временного ряда.
Временной ряд называется стационарным, если он не имеет тренда.
Оценку стационарности проведём в способами:
визуально,Дики-Фуллера.visual_stationarity_6(df_dro_24, list_features)
0%| | 0/9 [00:00<?, ?it/s]
Отмечаем:
Тест Дики-Фуллера (Dickey-Fuller test).
Тест заключается в том, что нужно выполнить статистическую проверку следующей гипотезы:
Используем пороговое значение, равное 0.05 (5%)
# Настроим, чтобы числа в датасетах отражались с 3 знаками после запятой
pd.set_option('display.float_format', '{:.3f}'.format)
df_test_DF = pd.DataFrame(columns=[
'source', 'ADF criterion', 'P-value', 'Critical value 1%',
'Critical values 5%', 'Conclusion'])
# Запуск исполнения теста
test_DF(df_dro_24, list_features)
# Просмотр датафрейма с результатами
display(df_test_DF)
# Удалим ненужный более датафрейм
del df_test_DF
| source | ADF criterion | P-value | Critical value 1% | Critical values 5% | Conclusion | |
|---|---|---|---|---|---|---|
| 0 | Telegram Web Desktop ADR | -2.242 | 0.191 | -3.518 | -2.900 | НЕ стационарен! |
| 1 | Telegram Web Desktop OTS | -1.785 | 0.388 | -3.517 | -2.899 | НЕ стационарен! |
| 2 | Telegram App Mobile ADR | -0.304 | 0.925 | -3.516 | -2.899 | НЕ стационарен! |
| 3 | Telegram App Mobile OTS | -0.801 | 0.819 | -3.516 | -2.899 | НЕ стационарен! |
| 4 | Telegram Web Mobile ADR | -7.664 | 0.000 | -3.512 | -2.897 | Стационарен. |
| 5 | Telegram Web Mobile OTS | -9.425 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 6 | ВКонтакте Web Desktop ADR | -2.851 | 0.051 | -3.516 | -2.899 | НЕ стационарен! |
| 7 | ВКонтакте Web Desktop OTS | -7.244 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 8 | ВКонтакте App Mobile ADR | -4.655 | 0.000 | -3.521 | -2.901 | Стационарен. |
| 9 | ВКонтакте App Mobile OTS | -2.151 | 0.224 | -3.523 | -2.902 | НЕ стационарен! |
| 10 | ВКонтакте Web Mobile ADR | -1.683 | 0.440 | -3.516 | -2.899 | НЕ стационарен! |
| 11 | ВКонтакте Web Mobile OTS | -4.272 | 0.000 | -3.511 | -2.897 | Стационарен. |
| 12 | Дзен Web Desktop ADR | -6.756 | 0.000 | -3.511 | -2.897 | Стационарен. |
| 13 | Дзен Web Desktop OTS | -5.209 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 14 | Дзен App Mobile ADR | -6.992 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 15 | Дзен App Mobile OTS | -6.415 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 16 | Дзен Web Mobile ADR | -5.919 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 17 | Дзен Web Mobile OTS | -5.884 | 0.000 | -3.510 | -2.896 | Стационарен. |
Промежуточные выводы для всех источников 'Telegram', 'ВКонтакте', 'Дзен' по возрастной группе от 25 до 34 лет:
# уберем из памяти ненужный более датафрейм.
del df_dro_24
ADR и OTS по возрастной категории 'от 35 до 44 лет'.¶Выделим из полного датафрейма, по всем возрастным группам, те записи, которые соответствуют выбранной возрастной группе.
print("Размер полного датафрейма:", df_dro.shape)
df_dro_35 = df_dro[df_dro.age == 35]
if (df_dro.shape[0] / 6 == df_dro_35.shape[0]):
print("Выделение части датафрейма проведено корректно.")
else:
print("Произошла потеря данных!")
print("Размер датафрейма по возрастной категории 'от 35 до 44 лет':",
df_dro_35.shape)
df_dro_35.head(3)
Размер полного датафрейма: (516, 20) Выделение части датафрейма проведено корректно. Размер датафрейма по возрастной категории 'от 35 до 44 лет': (86, 20)
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 258 | 2023-04-01 | 174100.000 | 2125100.000 | 10720000.000 | 146072600.000 | 27600.000 | 125600.000 | 1729300.000 | 58916700.000 | 10485100.000 | 109884600.000 | 2651400.000 | 29713000.000 | 1284300.000 | 13998800.000 | 240600.000 | 1469400.000 | 5718700.000 | 73913900.000 | 35 |
| 259 | 2023-04-02 | 207000.000 | 2528500.000 | 10559900.000 | 140762000.000 | 27300.000 | 128200.000 | 1767000.000 | 59096400.000 | 10472900.000 | 109568900.000 | 2558200.000 | 28232200.000 | 1429600.000 | 10585700.000 | 294100.000 | 1722700.000 | 5868800.000 | 77751900.000 | 35 |
| 260 | 2023-04-03 | 301800.000 | 3795900.000 | 11184000.000 | 168954400.000 | 27100.000 | 70800.000 | 2072800.000 | 81656000.000 | 10623600.000 | 118400900.000 | 2738000.000 | 29325900.000 | 1722800.000 | 17672000.000 | 239000.000 | 1682000.000 | 5981100.000 | 83322300.000 | 35 |
ADR и OTS по возрастной категории 'от 35 до 44 лет'.¶for key, value in dict_columns.items():
plot_average_daily_duration(df_dro_35, key, value)
Отмечаем, что данные от трех источников имеют разные масштабы:
Так как абсолютные значения нас не интересуют, интересует только поведение измеряемых величин, приведём все значения к одному масштабу.
# Настроим, чтобы числа в датасетах отражались без знаков после запятой
pd.set_option('display.float_format', '{:.0f}'.format)
# Создадим врЕменный датафрейм
df_dro_35_tmp = df_dro_35.copy()
for i in range(len(coeff_scale)):
df_dro_35_tmp[coeff_scale[i][0]] = df_dro_35_tmp[coeff_scale[i][0]].\
apply(lambda x: x * coeff_scale[i][1])
display(df_dro_35_tmp.head(3))
for key, value in dict_columns.items():
plot_average_daily_duration(df_dro_35_tmp, key, value)
# Удалим ненужный более датафрейм
del df_dro_35_tmp
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 258 | 2023-04-01 | 8705000 | 1062550 | 10720000 | 730363 | 5520000 | 125600 | 6917200 | 58916700 | 10485100 | 109884600 | 10605600 | 148565000 | 5137200 | 69994000 | 3609000 | 58776000 | 5718700 | 73913900 | 35 |
| 259 | 2023-04-02 | 10350000 | 1264250 | 10559900 | 703810 | 5460000 | 128200 | 7068000 | 59096400 | 10472900 | 109568900 | 10232800 | 141161000 | 5718400 | 52928500 | 4411500 | 68908000 | 5868800 | 77751900 | 35 |
| 260 | 2023-04-03 | 15090000 | 1897950 | 11184000 | 844772 | 5420000 | 70800 | 8291200 | 81656000 | 10623600 | 118400900 | 10952000 | 146629500 | 6891200 | 88360000 | 3585000 | 67280000 | 5981100 | 83322300 | 35 |
По выровненным к одному масштабу значеням графикам распределения можно отметить:
Используем Ящик с усами для отображения статистической информации о распределении Telegram Web Mobile OTS, такие как медиана, квартили и аномальные значения:
print('Аномальное значение "Telegram Web Mobile OTS":',
format_my(df_dro_35['Telegram Web Mobile OTS'].max()))
fig = plt.figure(figsize = (8,2))
sns.boxplot(df_dro_35['Telegram Web Mobile OTS'])
plt.xlabel("Эначения 'OTS' Telegram Web Mobile", fontsize=10, color='red')
plt.show;
Аномальное значение "Telegram Web Mobile OTS": 6,639,100.0
Отмечаем:
# Выберем исследуемый признак:
tmp = df_dro_35['Telegram Web Mobile OTS']
# Отсотрируем, начиная с максимального по убыванию:
display(tmp.sort_values(ascending = False).head(5))
271 6639100 288 455300 328 257500 279 227300 289 218400 Name: Telegram Web Mobile OTS, dtype: float64
# Посмотрим строку c индексом 271 с учётом того, что выше в общем
# датасете есть 3 более младшие возрастные категории по 86 записей:
df_dro_35.iloc[[271-86*3]]
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 271 | 2023-04-14 | 284100 | 2256700 | 11406400 | 170944100 | 88200 | 6639100 | 2042200 | 62297200 | 10503900 | 112308800 | 2514500 | 35263400 | 1673800 | 15053000 | 271100 | 1881600 | 5867200 | 76492600 | 35 |
Отмечаем:
Telegram Web Mobile OTS имеет ту же дату регистрации 14 апреля 2023, как и в предыдущих выборках!Изучим сезонную (периодическую) составляющую за неделю.
date_start, date_stop = '2023-04-01', '2023-04-16'
calc_print_weekday(date_start, date_stop)
volume_seasonal(df_dro_35, list_features)
Дни недели: 23-04-01 - Sat 23-04-02 - Sun 23-04-03 - Mon 23-04-04 - Tue 23-04-05 - Wed 23-04-06 - Thu 23-04-07 - Fri 23-04-08 - Sat 23-04-09 - Sun 23-04-10 - Mon 23-04-11 - Tue 23-04-12 - Wed 23-04-13 - Thu 23-04-14 - Fri 23-04-15 - Sat 23-04-16 - Sun
0%| | 0/9 [00:00<?, ?it/s]
Отмечаем:
Оценка стационарности временного ряда.
Временной ряд называется стационарным, если он не имеет тренда.
Оценку стационарности проведём в способами:
визуально,Дики-Фуллера.visual_stationarity_6(df_dro_35, list_features)
0%| | 0/9 [00:00<?, ?it/s]
Отмечаем:
Тест Дики-Фуллера (Dickey-Fuller test).
Тест заключается в том, что нужно выполнить статистическую проверку следующей гипотезы:
Используем пороговое значение, равное 0.05 (5%)
# Настроим, чтобы числа в датасетах отражались с 3 знаками после запятой
pd.set_option('display.float_format', '{:.3f}'.format)
df_test_DF = pd.DataFrame(columns=[
'source', 'ADF criterion', 'P-value', 'Critical value 1%',
'Critical values 5%', 'Conclusion'])
# Запуск исполнения теста
test_DF(df_dro_35, list_features)
# Просмотр датафрейма с результатами
display(df_test_DF)
# Удалим ненужный более датафрейм
del df_test_DF
| source | ADF criterion | P-value | Critical value 1% | Critical values 5% | Conclusion | |
|---|---|---|---|---|---|---|
| 0 | Telegram Web Desktop ADR | -2.307 | 0.170 | -3.516 | -2.899 | НЕ стационарен! |
| 1 | Telegram Web Desktop OTS | -3.725 | 0.004 | -3.514 | -2.898 | Стационарен. |
| 2 | Telegram App Mobile ADR | -0.872 | 0.797 | -3.516 | -2.899 | НЕ стационарен! |
| 3 | Telegram App Mobile OTS | 0.787 | 0.991 | -3.516 | -2.899 | НЕ стационарен! |
| 4 | Telegram Web Mobile ADR | -1.559 | 0.504 | -3.517 | -2.899 | НЕ стационарен! |
| 5 | Telegram Web Mobile OTS | -9.311 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 6 | ВКонтакте Web Desktop ADR | -1.454 | 0.556 | -3.517 | -2.899 | НЕ стационарен! |
| 7 | ВКонтакте Web Desktop OTS | -1.242 | 0.655 | -3.517 | -2.899 | НЕ стационарен! |
| 8 | ВКонтакте App Mobile ADR | -1.719 | 0.421 | -3.516 | -2.899 | НЕ стационарен! |
| 9 | ВКонтакте App Mobile OTS | -3.212 | 0.019 | -3.522 | -2.901 | Стационарен. |
| 10 | ВКонтакте Web Mobile ADR | -3.319 | 0.014 | -3.519 | -2.900 | Стационарен. |
| 11 | ВКонтакте Web Mobile OTS | -7.442 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 12 | Дзен Web Desktop ADR | -1.402 | 0.581 | -3.516 | -2.899 | НЕ стационарен! |
| 13 | Дзен Web Desktop OTS | -2.462 | 0.125 | -3.523 | -2.902 | НЕ стационарен! |
| 14 | Дзен App Mobile ADR | -7.561 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 15 | Дзен App Mobile OTS | -6.162 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 16 | Дзен Web Mobile ADR | -6.631 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 17 | Дзен Web Mobile OTS | -6.611 | 0.000 | -3.510 | -2.896 | Стационарен. |
Промежуточные выводы для всех источников 'Telegram', 'ВКонтакте', 'Дзен' по возрастной группе от 35 до 44 лет:
# уберем из памяти ненужный более датафрейм.
del df_dro_35
ADR и OTS по возрастной категории 'от 45 до 55 лет'.¶Выделим из полного датафрейма, по всем возрастным группам, те записи, которые соответствуют выбранной возрастной группе.
print("Размер полного датафрейма:", df_dro.shape)
df_dro_45 = df_dro[df_dro.age == 45]
if (df_dro.shape[0] / 6 == df_dro_45.shape[0]):
print("Выделение части датафрейма проведено корректно.")
else:
print("Произошла потеря данных!")
print("Размер датафрейма по возрастной категории 'от 45 до 55 лет':",
df_dro_45.shape)
df_dro_45.head(3)
Размер полного датафрейма: (516, 20) Выделение части датафрейма проведено корректно. Размер датафрейма по возрастной категории 'от 45 до 55 лет': (86, 20)
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 344 | 2023-04-01 | 106100.000 | 808700.000 | 7151500.000 | 85224000.000 | 27700.000 | 277300.000 | 1368200.000 | 42561700.000 | 6481300.000 | 60018000.000 | 1588500.000 | 13024200.000 | 1383400.000 | 13333300.000 | 292600.000 | 1271900.000 | 4815500.000 | 74602000.000 | 45 |
| 345 | 2023-04-02 | 135500.000 | 631200.000 | 7272900.000 | 87381500.000 | 39200.000 | 93600.000 | 1521200.000 | 65600500.000 | 6398700.000 | 62516300.000 | 1477100.000 | 14902800.000 | 1432200.000 | 14615800.000 | 283100.000 | 1499100.000 | 4845800.000 | 79409900.000 | 45 |
| 346 | 2023-04-03 | 168500.000 | 1099300.000 | 7533800.000 | 97691500.000 | 41100.000 | 115200.000 | 1751700.000 | 64642500.000 | 6302600.000 | 62142000.000 | 1555300.000 | 11975600.000 | 1648300.000 | 18192400.000 | 337300.000 | 1654300.000 | 4931400.000 | 82253400.000 | 45 |
ADR и OTS по возрастной категории 'от 45 до 55 лет'.¶for key, value in dict_columns.items():
plot_average_daily_duration(df_dro_45, key, value)
Отмечаем, что данные от трех источников имеют разные масштабы:
Так как абсолютные значения нас не интересуют, интересует только поведение измеряемых величин, приведём все значения к одному масштабу.
# Настроим, чтобы числа в датасетах отражались без знаков после запятой
pd.set_option('display.float_format', '{:.0f}'.format)
# Создадим врЕменный датафрейм
df_dro_45_tmp = df_dro_45.copy()
for i in range(len(coeff_scale)):
df_dro_45_tmp[coeff_scale[i][0]] = df_dro_45_tmp[coeff_scale[i][0]].\
apply(lambda x: x * coeff_scale[i][1])
display(df_dro_45_tmp.head(3))
for key, value in dict_columns.items():
plot_average_daily_duration(df_dro_45_tmp, key, value)
# Удалим ненужный более датафрейм
del df_dro_45_tmp
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 344 | 2023-04-01 | 5305000 | 404350 | 7151500 | 426120 | 5540000 | 277300 | 5472800 | 42561700 | 6481300 | 60018000 | 6354000 | 65121000 | 5533600 | 66666500 | 4389000 | 50876000 | 4815500 | 74602000 | 45 |
| 345 | 2023-04-02 | 6775000 | 315600 | 7272900 | 436908 | 7840000 | 93600 | 6084800 | 65600500 | 6398700 | 62516300 | 5908400 | 74514000 | 5728800 | 73079000 | 4246500 | 59964000 | 4845800 | 79409900 | 45 |
| 346 | 2023-04-03 | 8425000 | 549650 | 7533800 | 488458 | 8220000 | 115200 | 7006800 | 64642500 | 6302600 | 62142000 | 6221200 | 59878000 | 6593200 | 90962000 | 5059500 | 66172000 | 4931400 | 82253400 | 45 |
По выровненным к одному масштабу значеням графикам распределения можно отметить:
Изучим сезонную (периодическую) составляющую за неделю.
date_start, date_stop = '2023-04-01', '2023-04-16'
calc_print_weekday(date_start, date_stop)
volume_seasonal(df_dro_45, list_features)
Дни недели: 23-04-01 - Sat 23-04-02 - Sun 23-04-03 - Mon 23-04-04 - Tue 23-04-05 - Wed 23-04-06 - Thu 23-04-07 - Fri 23-04-08 - Sat 23-04-09 - Sun 23-04-10 - Mon 23-04-11 - Tue 23-04-12 - Wed 23-04-13 - Thu 23-04-14 - Fri 23-04-15 - Sat 23-04-16 - Sun
0%| | 0/9 [00:00<?, ?it/s]
Отмечаем:
Оценка стационарности временного ряда.
Временной ряд называется стационарным, если он не имеет тренда.
Оценку стационарности проведём в способами:
визуально,Дики-Фуллера.visual_stationarity_6(df_dro_45, list_features)
0%| | 0/9 [00:00<?, ?it/s]
Отмечаем:
Тест Дики-Фуллера (Dickey-Fuller test).
Тест заключается в том, что нужно выполнить статистическую проверку следующей гипотезы:
Используем пороговое значение, равное 0.05 (5%)
# Настроим, чтобы числа в датасетах отражались с 3 знаками после запятой
pd.set_option('display.float_format', '{:.3f}'.format)
df_test_DF = pd.DataFrame(columns=[
'source', 'ADF criterion', 'P-value', 'Critical value 1%',
'Critical values 5%', 'Conclusion'])
# Запуск исполнения теста
test_DF(df_dro_45, list_features)
# Просмотр датафрейма с результатами
display(df_test_DF)
# Удалим ненужный более датафрейм
del df_test_DF
| source | ADF criterion | P-value | Critical value 1% | Critical values 5% | Conclusion | |
|---|---|---|---|---|---|---|
| 0 | Telegram Web Desktop ADR | -7.431 | 0.000 | -3.512 | -2.897 | Стационарен. |
| 1 | Telegram Web Desktop OTS | -6.783 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 2 | Telegram App Mobile ADR | -0.924 | 0.780 | -3.516 | -2.899 | НЕ стационарен! |
| 3 | Telegram App Mobile OTS | 0.460 | 0.984 | -3.516 | -2.899 | НЕ стационарен! |
| 4 | Telegram Web Mobile ADR | -1.924 | 0.321 | -3.516 | -2.899 | НЕ стационарен! |
| 5 | Telegram Web Mobile OTS | -9.966 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 6 | ВКонтакте Web Desktop ADR | -1.153 | 0.693 | -3.523 | -2.902 | НЕ стационарен! |
| 7 | ВКонтакте Web Desktop OTS | -2.442 | 0.130 | -3.519 | -2.900 | НЕ стационарен! |
| 8 | ВКонтакте App Mobile ADR | -3.199 | 0.020 | -3.517 | -2.899 | Стационарен. |
| 9 | ВКонтакте App Mobile OTS | -1.759 | 0.401 | -3.516 | -2.899 | НЕ стационарен! |
| 10 | ВКонтакте Web Mobile ADR | -3.076 | 0.028 | -3.518 | -2.900 | Стационарен. |
| 11 | ВКонтакте Web Mobile OTS | -6.438 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 12 | Дзен Web Desktop ADR | -1.122 | 0.706 | -3.516 | -2.899 | НЕ стационарен! |
| 13 | Дзен Web Desktop OTS | -1.213 | 0.668 | -3.516 | -2.899 | НЕ стационарен! |
| 14 | Дзен App Mobile ADR | -7.246 | 0.000 | -3.511 | -2.897 | Стационарен. |
| 15 | Дзен App Mobile OTS | -7.349 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 16 | Дзен Web Mobile ADR | -6.976 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 17 | Дзен Web Mobile OTS | -0.595 | 0.872 | -3.515 | -2.898 | НЕ стационарен! |
Промежуточные выводы для всех источников 'Telegram', 'ВКонтакте', 'Дзен' по возрастной группе от 45 до 55 лет:
# уберем из памяти ненужный более датафрейм.
del df_dro_45
ADR и OTS по возрастной категории 'от 55 лет'.¶Выделим из полного датафрейма, по всем возрастным группам, те записи, которые соответствуют выбранной возрастной группе.
print("Размер полного датафрейма:", df_dro.shape)
df_dro_55 = df_dro[df_dro.age == 55]
if (df_dro.shape[0] / 6 == df_dro_55.shape[0]):
print("Выделение части датафрейма проведено корректно.")
else:
print("Произошла потеря данных!")
print("Размер датафрейма по возрастной категории 'от 55 лет':",
df_dro_55.shape)
df_dro_55.head(3)
Размер полного датафрейма: (516, 20) Выделение части датафрейма проведено корректно. Размер датафрейма по возрастной категории 'от 55 лет': (86, 20)
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 430 | 2023-04-01 | 103600.000 | 428600.000 | 7910000.000 | 72585000.000 | 15000.000 | 61600.000 | 1740600.000 | 38480800.000 | 6224100.000 | 48256900.000 | 2170500.000 | 13523300.000 | 2749400.000 | 37673600.000 | 783100.000 | 3772100.000 | 7866700.000 | 160823800.000 | 55 |
| 431 | 2023-04-02 | 107900.000 | 290500.000 | 8255900.000 | 75829700.000 | 60300.000 | 64900.000 | 1924400.000 | 62609600.000 | 6163900.000 | 52478800.000 | 2025400.000 | 9694900.000 | 2793800.000 | 40211300.000 | 875000.000 | 4515400.000 | 7974300.000 | 163560800.000 | 55 |
| 432 | 2023-04-03 | 107000.000 | 423700.000 | 8366000.000 | 82780600.000 | 62900.000 | 157700.000 | 1961700.000 | 44494600.000 | 6291100.000 | 53490500.000 | 1819900.000 | 11941000.000 | 3247800.000 | 47181400.000 | 798600.000 | 4590100.000 | 8404100.000 | 156795200.000 | 55 |
ADR и OTS по возрастной категории 'от 55 лет'.¶for key, value in dict_columns.items():
plot_average_daily_duration(df_dro_55, key, value)
Отмечаем, что данные от трех источников имеют разные масштабы:
Так как абсолютные значения нас не интересуют, интересует только поведение измеряемых величин, приведём все значения к одному масштабу.
# Настроим, чтобы числа в датасетах отражались без знаков после запятой
pd.set_option('display.float_format', '{:.0f}'.format)
# Создадим врЕменный датафрейм
df_dro_55_tmp = df_dro_55.copy()
for i in range(len(coeff_scale)):
df_dro_55_tmp[coeff_scale[i][0]] = df_dro_55_tmp[coeff_scale[i][0]].\
apply(lambda x: x * coeff_scale[i][1])
display(df_dro_55_tmp.head(3))
for key, value in dict_columns.items():
plot_average_daily_duration(df_dro_55_tmp, key, value)
# Удалим ненужный более датафрейм
del df_dro_55_tmp
| Date | Telegram Web Desktop ADR | Telegram Web Desktop OTS | Telegram App Mobile ADR | Telegram App Mobile OTS | Telegram Web Mobile ADR | Telegram Web Mobile OTS | ВКонтакте Web Desktop ADR | ВКонтакте Web Desktop OTS | ВКонтакте App Mobile ADR | ВКонтакте App Mobile OTS | ВКонтакте Web Mobile ADR | ВКонтакте Web Mobile OTS | Дзен Web Desktop ADR | Дзен Web Desktop OTS | Дзен App Mobile ADR | Дзен App Mobile OTS | Дзен Web Mobile ADR | Дзен Web Mobile OTS | age | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 430 | 2023-04-01 | 5180000 | 214300 | 7910000 | 362925 | 3000000 | 61600 | 6962400 | 38480800 | 6224100 | 48256900 | 8682000 | 67616500 | 10997600 | 188368000 | 11746500 | 150884000 | 7866700 | 160823800 | 55 |
| 431 | 2023-04-02 | 5395000 | 145250 | 8255900 | 379148 | 12060000 | 64900 | 7697600 | 62609600 | 6163900 | 52478800 | 8101600 | 48474500 | 11175200 | 201056500 | 13125000 | 180616000 | 7974300 | 163560800 | 55 |
| 432 | 2023-04-03 | 5350000 | 211850 | 8366000 | 413903 | 12580000 | 157700 | 7846800 | 44494600 | 6291100 | 53490500 | 7279600 | 59705000 | 12991200 | 235907000 | 11979000 | 183604000 | 8404100 | 156795200 | 55 |
По выровненным к одному масштабу значеням графикам распределения можно отметить:
Изучим сезонную (периодическую) составляющую за неделю.
date_start, date_stop = '2023-04-01', '2023-04-16'
calc_print_weekday(date_start, date_stop)
volume_seasonal(df_dro_55, list_features)
Дни недели: 23-04-01 - Sat 23-04-02 - Sun 23-04-03 - Mon 23-04-04 - Tue 23-04-05 - Wed 23-04-06 - Thu 23-04-07 - Fri 23-04-08 - Sat 23-04-09 - Sun 23-04-10 - Mon 23-04-11 - Tue 23-04-12 - Wed 23-04-13 - Thu 23-04-14 - Fri 23-04-15 - Sat 23-04-16 - Sun
0%| | 0/9 [00:00<?, ?it/s]
Отмечаем:
Оценка стационарности временного ряда.
Временной ряд называется стационарным, если он не имеет тренда.
Оценку стационарности проведём в способами:
визуально,Дики-Фуллера.visual_stationarity_6(df_dro_55, list_features)
0%| | 0/9 [00:00<?, ?it/s]
Отмечаем:
Тест Дики-Фуллера (Dickey-Fuller test).
Тест заключается в том, что нужно выполнить статистическую проверку следующей гипотезы:
Используем пороговое значение, равное 0.05 (5%)
# Настроим, чтобы числа в датасетах отражались с 3 знаками после запятой
pd.set_option('display.float_format', '{:.3f}'.format)
df_test_DF = pd.DataFrame(columns=[
'source', 'ADF criterion', 'P-value', 'Critical value 1%',
'Critical values 5%', 'Conclusion'])
# Запуск исполнения теста
test_DF(df_dro_55, list_features)
# Просмотр датафрейма с результатами
display(df_test_DF)
# Удалим ненужный более датафрейм
del df_test_DF
| source | ADF criterion | P-value | Critical value 1% | Critical values 5% | Conclusion | |
|---|---|---|---|---|---|---|
| 0 | Telegram Web Desktop ADR | -7.294 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 1 | Telegram Web Desktop OTS | -3.351 | 0.013 | -3.513 | -2.897 | Стационарен. |
| 2 | Telegram App Mobile ADR | -3.341 | 0.013 | -3.517 | -2.899 | Стационарен. |
| 3 | Telegram App Mobile OTS | -3.265 | 0.017 | -3.522 | -2.901 | Стационарен. |
| 4 | Telegram Web Mobile ADR | -4.278 | 0.000 | -3.512 | -2.897 | Стационарен. |
| 5 | Telegram Web Mobile OTS | -5.297 | 0.000 | -3.513 | -2.897 | Стационарен. |
| 6 | ВКонтакте Web Desktop ADR | -1.260 | 0.647 | -3.518 | -2.900 | НЕ стационарен! |
| 7 | ВКонтакте Web Desktop OTS | -5.516 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 8 | ВКонтакте App Mobile ADR | -2.126 | 0.234 | -3.516 | -2.899 | НЕ стационарен! |
| 9 | ВКонтакте App Mobile OTS | -1.587 | 0.490 | -3.516 | -2.899 | НЕ стационарен! |
| 10 | ВКонтакте Web Mobile ADR | -3.181 | 0.021 | -3.512 | -2.897 | Стационарен. |
| 11 | ВКонтакте Web Mobile OTS | -6.944 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 12 | Дзен Web Desktop ADR | -2.292 | 0.175 | -3.518 | -2.900 | НЕ стационарен! |
| 13 | Дзен Web Desktop OTS | -3.802 | 0.003 | -3.519 | -2.900 | Стационарен. |
| 14 | Дзен App Mobile ADR | -1.823 | 0.369 | -3.514 | -2.898 | НЕ стационарен! |
| 15 | Дзен App Mobile OTS | -2.058 | 0.262 | -3.513 | -2.897 | НЕ стационарен! |
| 16 | Дзен Web Mobile ADR | -6.793 | 0.000 | -3.510 | -2.896 | Стационарен. |
| 17 | Дзен Web Mobile OTS | -5.316 | 0.000 | -3.510 | -2.896 | Стационарен. |
Промежуточные выводы для всех источников 'Telegram', 'ВКонтакте', 'Дзен' по возрастной группе от 55 лет:
# уберем из памяти ненужный более датафрейм.
del df_dro_55
По результатам исследования можно отметить следующие факты и сделать приводимые ниже выводы:
Daily_Reach_OTS_total находятся примерно 516 записей и 152 признака.